package com.yy.wga.mp.module.user.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.PageHelper;
import com.yy.wga.common.core.dto.Result;
import com.yy.wga.common.core.exception.BusinessException;
import com.yy.wga.mp.common.contants.MpConstant;
import com.yy.wga.mp.common.dto.UserCacheDTO;
import com.yy.wga.mp.common.interceptor.RequestUserHolder;
import com.yy.wga.mp.common.utils.mapping.BeansUtils;
import com.yy.wga.mp.module.user.entity.pojo.UserBaseDO;
import com.yy.wga.mp.module.user.entity.pojo.UserRelationDO;
import com.yy.wga.mp.module.user.request.MpLockFansRequest;
import com.yy.wga.mp.module.user.request.UserRelationListRequest;
import com.yy.wga.mp.module.user.response.UserRelationListResponse;
import com.yy.wga.mp.module.user.service.UserBaseService;
import com.yy.wga.mp.module.user.service.UserRelationService;
import com.yy.wga.user.feign.api.UserFeign;
import com.yy.wga.user.feign.request.LockFansRequest;
import com.yy.wga.user.feign.response.LockFansResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 直播用户锁粉关系(UserRelation)表服务实现类
 *
 * @author guochao
 * @since 2022-07-27 22:12:32
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserRelationServiceImpl implements UserRelationService {

    private final StringRedisTemplate stringRedisTemplate;
    private final UserBaseService userBaseService;
    private final UserFeign userFeign;

    @Override
    @Transactional
    public void lockFans(MpLockFansRequest request) {
        UserCacheDTO userCache = RequestUserHolder.getUserCache();
        LockFansRequest lockFansRequest = new LockFansRequest();
        lockFansRequest.setParentUserId(request.getParentUserId());
        lockFansRequest.setInviteCode(request.getInviteCode());
        lockFansRequest.setUserId(userCache.getUserId());
        Result<LockFansResponse> lockFansResponseResult = userFeign.lockFans(lockFansRequest);
        if (!lockFansResponseResult.isSuccess()) {
            throw new BusinessException(lockFansResponseResult.getMessage());
        }
        LockFansResponse response = lockFansResponseResult.getData();

        // 更新缓存
        userCache.setInviteCode(response.getInviteCode());
        userCache.setGrade(response.getGrade());
        userCache.setLevel(response.getLevel());
        String redisKey = MpConstant.USER_INFO + userCache.getToken();
        stringRedisTemplate.opsForValue().set(redisKey, JSON.toJSONString(userCache), 6, TimeUnit.HOURS);
    }

    @Override
    public void removeByUserId(Long userId) {
        baseMapper.removeByUserId(userId);
    }

    @Override
    public void removeByParentUserId(Long parentUserId) {
        baseMapper.removeByParentUserId(parentUserId);
    }

    @Override
    public List<UserRelationListResponse> listData(UserRelationListRequest request) {
        PageHelper.startPage(request.getPageNum(), request.getPageSize(), false);
        List<UserRelationDO> userRelationList = baseMapper.selectList(new LambdaQueryWrapper<UserRelationDO>()
                .eq(UserRelationDO::getAppKey, RequestUserHolder.getBaseRequest().getAppKey())
                .eq(UserRelationDO::getParentUserId, RequestUserHolder.getUserCache().getUserId())
                .eq(request.getGrade() != null, UserRelationDO::getGrade, request.getGrade())
                .eq(request.getLevel() != null, UserRelationDO::getLevel, request.getLevel())
                .orderByDesc(UserRelationDO::getId));
        if (CollectionUtils.isEmpty(userRelationList)) {
            return Collections.emptyList();
        }
        List<Long> userIds = userRelationList.stream().map(UserRelationDO::getUserId).collect(Collectors.toList());
        List<UserBaseDO> userBaseList = userBaseService.listByIds(userIds);
        Map<Long, UserBaseDO> userMap = userBaseList.stream()
                .collect(Collectors.toMap(UserBaseDO::getId, Function.identity()));

        List<UserRelationListResponse> responseList = new ArrayList<>();
        for (UserRelationDO userRelation : userRelationList) {
            UserRelationListResponse response = BeansUtils.map(userRelation, UserRelationListResponse.class);
            response.setUserId(userRelation.getUserId());
            response.setLockFanTime(userRelation.getCreateTime());
            UserBaseDO userBaseDO = userMap.get(response.getUserId());
            if (userBaseDO != null) {
                response.setAvatarUrl(userBaseDO.getAvatarUrl());
                response.setNickName(userBaseDO.getNickName());
            }
            responseList.add(response);
        }
        return responseList;
    }
}
